package io.esirong.manager;

import android.os.Parcel;
import android.os.Parcelable;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.Serializable;

import androidx.annotation.NonNull;

/**
 * AccessToken（BEAN)
 * Created by 黄嵘才 on 2017/7/6.
 */

public class AccessToken implements Parcelable, Serializable {

    /* Constants related to JSON serialization.*/

    private static final int CURRENT_JSON_FORMAT = 1;
    private static final String VERSION_KEY = "version";
    private static final String EXPIRES_AT_KEY = "expires_at";
    private static final String TOKEN_KEY = "token";
    private static final String LAST_REFRESH_KEY = "last_refresh";

    private final String token;
    private final String refreshToken;
    private final long expires;

    public AccessToken(
            final String token,
            final String refreshToken,
            final long expiresOn) {
        this.token = token;
        this.refreshToken = refreshToken;
        this.expires = expiresOn;
    }

    /**
     * Gets the string representing the access token.
     *
     * @return the string representing the access token
     */
    public String getToken() {
        return this.token;
    }

    public String getRefreshToken() {
        return this.refreshToken;
    }

    /**
     * Gets the date at which the access token expires.
     *
     * @return the expiration date of the token
     */
    public long getExpires() {
        return this.expires;
    }

    @NonNull
    JSONObject toJSONObject() throws JSONException {
        JSONObject jsonObject = new JSONObject();

        jsonObject.put(VERSION_KEY, CURRENT_JSON_FORMAT);
        jsonObject.put(TOKEN_KEY, token);
        jsonObject.put(EXPIRES_AT_KEY, expires);
        jsonObject.put(LAST_REFRESH_KEY, refreshToken);

        return jsonObject;
    }

    @NonNull
    static AccessToken createFromJSONObject(@NonNull JSONObject jsonObject) throws JSONException {
        String token = jsonObject.getString(TOKEN_KEY);
        long expiresAt = jsonObject.getLong(EXPIRES_AT_KEY);
        String lastRefresh = jsonObject.getString(LAST_REFRESH_KEY);

        return new AccessToken(
                token,
                lastRefresh,
                expiresAt);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.token);
        dest.writeString(this.refreshToken);
        dest.writeLong(this.expires);
    }

    protected AccessToken(Parcel in) {
        this.token = in.readString();
        this.refreshToken = in.readString();
        this.expires = in.readLong();
    }

    public static final Creator<AccessToken> CREATOR = new Creator<AccessToken>() {
        @Override
        public AccessToken createFromParcel(Parcel source) {
            return new AccessToken(source);
        }

        @Override
        public AccessToken[] newArray(int size) {
            return new AccessToken[size];
        }
    };

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof AccessToken)) {
            return false;
        }

        AccessToken that = (AccessToken) o;

        if (expires != that.expires) {
            return false;
        }
        if (!token.equals(that.token)) {
            return false;
        }
        return refreshToken.equals(that.refreshToken);
    }

    @Override
    public int hashCode() {
        int result = token.hashCode();
        result = 31 * result + refreshToken.hashCode();
        result = 31 * result + (int) (expires ^ (expires >>> 32));
        return result;
    }
}
